package me.suntao.javaio.server.nio2;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;

/**
 * NIO2EchoServer
 * Created by suntao on 2017/6/6.
 */
public class Nio2EchoServer {

  private static final int DEFAULT_PORT = 28000;
  /**
   * main函数
   * @param args
   */
  public static void main(String[] args)
    throws IOException, ExecutionException, InterruptedException {

    try(final AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()){
      if(serverSocketChannel.isOpen()){
        serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF,4*1024);
        serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR,true);
        serverSocketChannel.bind(new InetSocketAddress(DEFAULT_PORT));
        System.out.println("服务器等待连接。。。");
        serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {

          final ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

          @Override public void completed(final AsynchronousSocketChannel channel, Void attachment) {
            //接收下一个连接
            serverSocketChannel.accept(null,this);
            try {
              System.out.println(Thread.currentThread().getName()+System.currentTimeMillis()+" client:"+channel.getRemoteAddress());
              String msg = String
                .format("server_name:%s, sent_time:%s", Thread.currentThread().getName(), System.currentTimeMillis());
              final ByteBuffer writeBuffers = ByteBuffer.wrap(msg.getBytes("UTF-8"));
              channel.write(writeBuffers, writeBuffers, new CompletionHandler<Integer, ByteBuffer>() {
                @Override public void completed(Integer result, ByteBuffer attachment) {
                  //还有字节则继续发送
                  if(attachment.hasRemaining()){
                    channel.write(attachment,attachment,this);
                  }
                  System.out.println("server_name:"+Thread.currentThread().getName()+" sendBytes: "+result);
                }

                @Override public void failed(Throwable exc, ByteBuffer attachment) {
                  System.out.println("server_name:"+Thread.currentThread().getName()+"发送失败："+exc.getMessage());
                  exc.printStackTrace();
                }
              });
//              while (result.read(buffer).get()!=-1){
//                buffer.flip();
//                result.write(buffer);
//                if(buffer.hasRemaining()){
//                  buffer.compact();
//                }else{
//                  buffer.clear();
//                }
//              }
            } catch (IOException  e) {
              e.printStackTrace();
            }finally {
              try {
                System.out.println(Thread.currentThread().getName()+System.currentTimeMillis()+" closed");
//                result.close();
              } catch (Exception e) {
                e.printStackTrace();
              }
            }
          }

          @Override public void failed(Throwable exc, Void attachment) {
            serverSocketChannel.accept(null,this);
          }
        });
      }


      System.in.read();
    }catch (IOException  ex){
      ex.printStackTrace();
    }

  }
}
